package sk.tonyb.library.projectpaths;

import java.io.File;

import org.apache.log4j.Logger;

/** 
 * Class, which stores information about application paths. <br>
 * 
 * @author Anton Balucha
 * @since 11.03.2011
 * @last_modified 23.10.2011
 */
public class ProjectPathDesktop implements IProjectPath {
	
	/** Log4j logger. */
	private static final Logger logger = Logger.getLogger(ProjectPathDesktop.class);

	/** Variable, which store singleton. */
	private static ProjectPathDesktop projectPathWeb = null;
	
	private String classSource = null;
	private String projectName = null;
	private String pathToProject = null;
	private String pathToProjectDirectory = null;
	private String pathToWebInf = null;
	private String pathToBinDirectory = null;
	private String pathToClassesDirectory = null;
	private String pathToConfigurationDirectory = null;
	private String pathToConfigurationFile = null;

	/** Constructor. */
	private ProjectPathDesktop() {
		this.init();
	}
	
	/** Method, which return unique instance of ProjectPath - singleton. */
	public static synchronized ProjectPathDesktop getInstance() {
		
		if(ProjectPathDesktop.projectPathWeb == null) {
			ProjectPathDesktop.projectPathWeb = new ProjectPathDesktop();
		}
		
		return ProjectPathDesktop.projectPathWeb;
	}
	
	/** Method, which provides calling of initialization methods. */
	private synchronized void init() {
		this.initPaths();
		this.initLinuxPaths();
		this.printValues();
	}
	
	/** Method, which initialize paths. */
	private synchronized void initPaths() {
		
		String help = null;
		
		this.classSource = ProjectPathDesktop.class.getResource("").toString();
		
		help = this.classSource.replace("file:/", "").replace(ProjectPathDesktop.class.getCanonicalName().replace(ProjectPathDesktop.class.getSimpleName(), "").replace(".", "/"), "");
		help = (help.endsWith("bin/") ? help.replace("bin/", "") : (help.endsWith("classes/") ? help.replace("classes/", "") : help));
		help = help.replace("/", File.separator);
		
		this.pathToProject = help.substring(0, help.substring(0, help.lastIndexOf(File.separator) - 1).lastIndexOf(File.separator)) + File.separator;
		
		this.pathToProjectDirectory = help;
		
		this.projectName = this.pathToProjectDirectory.replace(this.pathToProject, "").replace(File.separator, "");
		
		this.pathToBinDirectory = this.pathToProjectDirectory + IProjectPath.BIN + File.separator;
		
		this.pathToClassesDirectory = this.pathToProjectDirectory + IProjectPath.CLASSES + File.separator;
		
		this.pathToConfigurationDirectory = this.pathToProjectDirectory + IProjectPath.CONFIGURATION_DIRECTORY + File.separator;
		
		this.pathToConfigurationFile = this.pathToConfigurationDirectory + IProjectPath.CONFIGURATION_FILE_NAME_CONFIG_PROPERTIES + File.separator;
	}
	
	/** Method, which check, if OS is Linux. If OS is Linux, paths will be corrected - they will start with slash /. */
	private synchronized void initLinuxPaths() {
		
		if(!System.getProperty(IProjectPath.SYSTEM_PROPERTY_OS_NAME).toLowerCase().contains(IProjectPath.OPERATION_SYSTEM_WIN)) {
			
			if(this.classSource.startsWith(File.separator) == false) {
				this.classSource = File.separator + this.classSource;
			}
			
			if(this.pathToProject.startsWith(File.separator) == false) {
				this.pathToProject = File.separator + this.pathToProject;
			}

			if(this.pathToProjectDirectory.startsWith(File.separator) == false) {
				this.pathToProjectDirectory = File.separator + this.pathToProjectDirectory;
			}
			
			if(this.pathToWebInf.startsWith(File.separator) == false) {
				this.pathToWebInf = File.separator + this.pathToWebInf;
			}
			
			if(this.pathToBinDirectory.startsWith(File.separator) == false) {
				this.pathToBinDirectory = File.separator + this.pathToBinDirectory;
			}
			
			if(this.pathToClassesDirectory.startsWith(File.separator) == false) {
				this.pathToClassesDirectory = File.separator + this.pathToClassesDirectory;
			}
			
			if(this.pathToConfigurationDirectory.startsWith(File.separator) == false) {
				this.pathToConfigurationDirectory = File.separator + this.pathToConfigurationDirectory;
			}
			
			if(this.pathToConfigurationFile.startsWith(File.separator) == false) {
				this.pathToConfigurationFile = File.separator + this.pathToConfigurationFile;
			}
		}
	}

	/** Return class source. E.g. "file:/C:/java/apache/ProjectName/WEB-INF/classes/Packages/" */
	@Override
	public synchronized String getClassSource() {
		return this.classSource;
	}
	
	/** Return project name. E.g. "ProjectName" */
	@Override
	public synchronized String getProjectName() {
		return this.projectName;
	}
	
	/** Return path to project. E.g. "C:\java\apache\" */
	@Override
	public synchronized String getPathToProject() {
		return this.pathToProject;
	}
	
	/** Return path with project. E.g. "C:\java\apache\ProjectName\" */
	@Override
	public synchronized String getPathToProjectDirectory() {
		return this.pathToProjectDirectory; 
	}
	
	/** Return path to data directory. E.g. "C:\java\apache\ProjectName\WEB-INF\" */
	@Override
	public synchronized String getPathToWebInf() {
		return this.pathToWebInf;
	}

	/** Return path to bin. E.g. "C:\java\apache\ProjectName\bin\" */
	@Override
	public synchronized String getPathToBinDirectory() {
		return this.pathToBinDirectory;
	}
	
	/** Return path to classes. E.g. "C:\java\apache\ProjectName\classes\" */
	@Override
	public synchronized String getPathClassesDirectory() {
		return this.pathToClassesDirectory;
	}
	
	/** Return path to configuration directory. E.g. "C:\java\apache\ProjectName\ConfigurationDirectory\" */
	@Override
	public synchronized String getPathConfigurationDirectory() {
		return this.pathToConfigurationDirectory;
	}
	
	/** Return path to configuration directory. E.g. "C:\java\apache\ProjectName\ConfigurationDirectory\config.xml" */
	@Override
	public synchronized String getPathConfigurationFile() {
		return this.pathToConfigurationFile;
	}
	
	/** Method, which print values. */
	@Override
	public synchronized void printValues() {
		
		logger.info("--------------------BEGINNING OF INFORMATION ABOUT PROJECT PATHS-----------------------------------");
		logger.info("ProjectPath.getClassSource(): " + this.getClassSource());
		logger.info("ProjectPath.getProjectName(): " + this.getProjectName());
		logger.info("ProjectPath.getPathToProject(): " + this.getPathToProject());
		logger.info("ProjectPath.getPathToProjectDirectory(): " + this.getPathToProjectDirectory());
		logger.info("ProjectPatch.getPathToWebInf(): " + this.getPathToWebInf());
		logger.info("ProjectPatch.getPathToBinDirectory(): " + this.getPathToBinDirectory());
		logger.info("ProjectPatch.getPathClassesDirectory(): " + this.getPathClassesDirectory());
		logger.info("ProjectPath.getPathConfigurationDirectory(): " + this.getPathConfigurationDirectory());
		logger.info("ProjectPath.getPathConfigurationFile(): " + this.getPathConfigurationFile());
		logger.info("--------------------END OF INFORMATION ABOUT PROJECT PATHS-----------------------------------");
	}
	
	public static void main(String[] args) {
		
		ProjectPathDesktop.getInstance();
		
	}
}
